use std::env;
use std::ops::Add;
use serde::{Deserialize, Serialize};
use crate::utils::tool::read_json;

/// AppConfig 系统配置信息
#[derive(Debug, Serialize, Deserialize)]
pub struct AppConfig {
    pub port: u32,
    pub host: String,
    pub db: DbConfig,
    pub redis: RedisConfig,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DbConfig {
    pub host: String,
    pub port: u32,
    pub database: String,
    pub username: String,
    pub password: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RedisConfig {
    pub host: String,
    pub port: u32,
    pub database: u8,
    pub password: String,
}

impl DbConfig {
    pub fn link(&self) -> String {
        format!("postgresql://{}:{}?dbname={}&user={}&password={}", self.host, self.port, self.database, self.username, self.password)
    }
}

impl RedisConfig {
    pub fn link(&self) -> String {
        format!("redis://:{}@{}:{}/{}", self.password, self.host, self.port, self.database)
    }
}

impl AppConfig {
    pub fn local_addr(&self) -> String {
        format!("{}:{}", self.host, self.port)
    }
}

impl Default for AppConfig {
    fn default() -> Self {
        let current_dir = env!("CARGO_MANIFEST_DIR");
        let path = current_dir.to_owned().add("/config.json");
        let ctx =  match read_json(&path) {
            Ok(data) => data,
            Err(err) => panic!("配置文件读取失败: {}", err),
        };
        match serde_json::from_str(&ctx) {
            Ok(config) => config,
            Err(_) => panic!("解析配置文件失败")
        }
    }
}

